﻿using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sern.Abstracts.Tracker.DataContracts;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Abstracts.Tracker.ServiceContracts.Fakes;
using Sern.Common;
using Sern.Common.Fakes;
using Sern.ServiceImplementation.TrackerDefinition;
using Sern.ServiceImplementation.TrackerDefinition.Data;

namespace Sern.Test.ServiceImplementation.TrackerDefinition
{
    [TestClass]
    public class TrackerCommon_NotifiesUnsubscriberToMonitor
    {
        private ClientLeftNotice _recordedClient1LeftNotification = null;
        private bool _isMonitor1ProxyDisposalCalled = false;

        [TestInitialize]
        public void Initialize()
        {
            ComponentLocator.Reset();

            ComponentLocator.Unity.RegisterInstance(
                    RepositoryFactory.CreateStub<Client>());

            //Wire up the fake monitor.
            ComponentLocator.Unity.RegisterInstance<IEnumerable<IClient<ITrackerMonitoringClient>>>(
                new StubIClient<ITrackerMonitoringClient>[]
                    {
                        new StubIClient<ITrackerMonitoringClient>
                            {
                                ProxyGet = () =>
                                    new StubITrackerMonitoringClient
                                    {
                                        NotifyClientLeftNotice = notice => _recordedClient1LeftNotification = notice,
                                    },
                                    Dispose = () => _isMonitor1ProxyDisposalCalled = true
                            },
                    });

            ComponentLocator.Unity.RegisterTestInstance(Guid.NewGuid(), "jobId");

            ComponentLocator.Unity.RegisterTestInstance(
                new ClientInfo
                {
                    JobId = ComponentLocator.Unity.ResolveTest<Guid>("jobId"),
                    Id = Guid.NewGuid(),
                    KeyShape = "NewKey.Shape",
                    Type = ClientType.Tracker,
                    Uri = "asdf",
                    ValueShape = "SomeValue.Shape",
                    HostUri = "http://clientHost:8080"
                },
                    "client1"
                );
        }

        [TestMethod]
        public void Test()
        {
            //All subscription should be empty.
            Assert.IsFalse(_isMonitor1ProxyDisposalCalled);
            Assert.IsNull(_recordedClient1LeftNotification);

            var client1Info = ComponentLocator.Unity.ResolveTest<ClientInfo>("client1");
            TrackerCommon.Subscribe(
                client1Info.JobId,
                client1Info.Id,
                client1Info.Type,
                client1Info.Uri,
                client1Info.KeyShape,
                client1Info.ValueShape,
                client1Info.HostUri
                );

            TrackerCommon.Unsubscribe(
                client1Info.Id
                );

            //All subscription should be empty.
            Assert.IsTrue(_isMonitor1ProxyDisposalCalled);
            Assert.IsTrue(_recordedClient1LeftNotification.OldClient.Id == client1Info.Id);
            Assert.IsTrue(_recordedClient1LeftNotification.OldClient.Uri == client1Info.Uri);
        }
    }
}
